home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** Program: MacShell
- ** File: utils.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1990-1991 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "MacShell.h" /* Get the MacShell includes/typedefs, etc. */
- #include "MacShellCommon.h" /* Get the stuff in common with rez. */
- #include "MacShell.protos" /* Get the prototypes for MacShell. */
-
- #ifndef __STRING__
- #include <String.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifdef THINK_C
- #include "Utilities.h"
- #else
- #ifndef __UTILITIES__
- #include <Utilities.h>
- #endif
- #endif
-
-
-
- #define BASE 10
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void appendi2cstr(char *cstr, short i)
- {
- i2cstr(cstr + strlen(cstr), i);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- short appendi2pstr(char *pstr, short i)
- {
- short j;
-
- j = 0;
- if (i >= BASE) j = appendi2pstr(pstr, i / BASE);
- pstr[++*pstr] = "0123456789ABCDEF"[i - j];
- return(BASE * i);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- short i2cstr(char *cstr, short i)
- {
- short j;
-
- cstr[1] = j = 0;
- if (i >= BASE)
- j = i2cstr(cstr + 1, i / BASE);
- *cstr = "0123456789ABCDEF"[i - j];
- return(BASE * i);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void i2pstr(char *pstr, short i)
- {
- *pstr = 0;
- appendi2pstr(pstr, i);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void pstrcat(char *d, char *s)
- {
- short i;
-
- for (i = 0; i < s[0];)
- d[++d[0]] = s[++i];
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void pstrcpy(char *d, char *s)
- {
- short i;
-
- i = *s;
- do {
- d[i] = s[i];
- } while (i--);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- short GetHexByte(char *cptr)
- {
- short val, i, chr;
-
- for (val = 0, i = 0; i < 2; ++i) {
- chr = cptr[i];
- if (chr == '=') return(cptr[++i]);
- if (chr > 'F') chr -= 0x20;
- if (chr > '9') chr -= ('A' - '9' - 1);
- val = (val << 4) + chr - '0';
- }
- return(val);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- pascal Boolean alertFilter(DialogPtr dlg, EventRecord *event, short *item)
- {
- short what, theChr, theMod, handled;
-
- what = event->what;
- if (event->what == keyDown) {
- theChr = event->message & charCodeMask;
- theMod = event->modifiers & keyCodeMask;
- if ((theChr != 0x0D) && (theChr != 0x03)) event->what = nullEvent;
- if (theMod & (cmdKey + optionKey + controlKey)) event->what = nullEvent;
- }
- handled = keyEquivFilter(dlg, event, item);
- event->what = what;
- return(handled);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- /* This code expects the key equivalents to be in item #2, which is a StatText
- ** item that is located so the text is outside of the dialog. This allows us
- ** to put key equivalent information in the resource fork, so the key
- ** equivalents are localizable.
- **
- ** An example save changes before closing or quitting res source with
- ** keyEquiv info would look like:
- **
- ** resource 'DITL' (rYesNoCancel, purgeable) {
- ** {
- ** {71, 315, 91, 367}, Button { enabled, "Save" },
- ** {0, -1000, 20, 2}, StaticText { disabled,
- ** "=S190001,=s190001,=D190003,=d190003,=.190104,1B190004" },
- ** {71, 80, 91, 162}, Button { enabled, "Don’t Save" },
- ** {71, 244, 91, 302}, Button { enabled, "Cancel" },
- ** {11, 78, 61, 366}, StaticText { disabled,
- ** "Save changes to the document “^0” before ^1?" },
- ** {11, 23, 43, 55}, Icon { disabled, 2 }
- ** }
- ** };
- **
- ** The document name would be the string for param #0.
- ** The text "closing" or "quitting" would be the string for param #1.
- **
- ** The keyEquiv entry is item #2, which has a rect that pushes it out of the
- ** dialog. The string info is interpreted as to what the key/modifier combo
- ** is, and what dialog item it relates to.
- **
- ** A single key equiv entry is 8 characters. Entries are separated by commas.
- **
- ** If the first character of an entry is an =, then the next character is the
- ** key. If the first character isn't an =, then the first two characters are
- ** the hex value of the key. (Ex: =S or =s for save, 1B for ESC.)
- **
- ** If the key pressed is the same as the key value for any of the entries, then
- ** the next two characters are the hex value for which modifiers to test. This
- ** modifier test value is anded with the modifier. The result is then compared
- ** to the value of the next two hex digits. If they are equal, then the
- ** modifiers are correct, as well as the key. If this is so, we have a winner.
- **
- ** "=S190001,=s190001,=D190003,=d190003,=.190104,1B190004"
- **
- ** The above string breaks down as follows:
- ** =S190001 =S if event keypress is an S, check the modifier values
- ** 19 check controlKey/optionKey/cmdKey
- ** 00 all modifiers we are testing for should be false
- ** 01 if above is true, keypress maps to item # 1
- ** =s190001 Same as =S, but lowercase
- ** =D190001 Same as =S, but maps to item #3
- ** =d190001 Same as =D, but lowercase
- ** =.190104 =. if event keypress is a period, check the modifier values
- ** 19 check controlKey/optionKey/cmdKey
- ** 01 controlKey/optionKey should be false, cmdKey should be true
- ** 04 if above is true, keypress maps to item # 4
- ** 1B190004 1B if event keypress is an ESC, check the modifier values
- ** 19 check controlKey/optionKey/cmdKey
- ** 00 all modifiers we are testing for should be false
- ** 04 if above is true, keypress maps to item # 4
- */
-
- #pragma segment Main
- pascal Boolean keyEquivFilter(DialogPtr dlg, EventRecord *event, short *item)
- {
- short itemType;
- Handle itemHndl;
- Rect itemRect;
- Str255 itemText;
- short i, theChr, theMod, equivChr, modMask, modVal, itemNum;
- long tick;
-
- if (event->what == updateEvt) {
- if (dlg == (DialogPtr)event->message) OutlineDialogItem(dlg, 1);
- return(false);
- }
-
- if (event->what != keyDown) return(false);
-
- itemNum = 0;
-
- theChr = event->message & charCodeMask;
- theMod = event->modifiers & keyCodeMask;
-
- if ((theChr == 0x0D) || (theChr == 0x03)) { /* If return or enter... */
- if (!(theMod & (cmdKey + optionKey + controlKey))) itemNum = 1;
- }
- else {
-
- GetDItem(dlg, 2, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, itemText);
-
- for (i = 1; i <= *itemText; i += 9) {
- equivChr = GetHexByte((char *)(itemText + i));
- modMask = GetHexByte((char *)(itemText + i + 2)) << 8;
- modVal = GetHexByte((char *)(itemText + i + 4)) << 8;
- itemNum = GetHexByte((char *)(itemText + i + 6));
- if (theChr == equivChr)
- if ((theMod & modMask) == modVal) break;
- itemNum = 0;
- }
- }
-
- if (itemNum) {
- GetDItem(dlg, itemNum, &itemType, &itemHndl, &itemRect);
- HiliteControl((ControlHandle)itemHndl, 1);
- tick = TickCount();
- while (TickCount() < tick + 10);
- HiliteControl((ControlHandle)itemHndl, 0);
- *item = itemNum;
- return(true);
- }
-
- return(false);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void OffsetControl(ControlHandle ctl, short dx, short dy)
- {
- Rect ctlRect;
-
- ctlRect = (*ctl)->contrlRect;
- MoveControl(ctl, ctlRect.left + dx, ctlRect.top + dy);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void DoDrawGrowIcon(WindowPtr window, Boolean horLine, Boolean verLine)
- {
- WindowPtr oldPort;
- Rect rct;
- RgnHandle oldClip, newClip;
-
- GetPort(&oldPort);
- SetPort(window);
-
- rct = window->portRect;
- rct.left = rct.right - 15;
- rct.top = rct.bottom - 15;
-
- if (window != FrontWindow()) {
- FrameRect(&rct);
- ++rct.top;
- ++rct.left;
- EraseRect(&rct);
- SetPort(oldPort);
- return;
- }
-
- oldClip = NewRgn();
- newClip = NewRgn();
-
- if (horLine) rct.left = window->portRect.left;
- if (verLine) rct.top = window->portRect.top;
- RectRgn(newClip, &rct);
-
- GetClip(oldClip);
- SetClip(newClip);
- DrawGrowIcon(window); /* Draw grow icon without scrollbar lines. */
-
- SetClip(oldClip);
- DisposeRgn(oldClip);
- DisposeRgn(newClip);
-
- SetPort(oldPort);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void DoDrawControls(WindowPtr window, Boolean scrollBarsOnly)
- {
- ControlHandle ctl;
-
- ctl = ((WindowPeek)window)->controlList;
- while (ctl) {
- DoDraw1Control(ctl, scrollBarsOnly);
- ctl = (*ctl)->nextControl;
- }
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Main
- void DoDraw1Control(ControlHandle ctl, Boolean scrollBarsOnly)
- {
- Boolean front;
- WindowPtr window, oldPort;
- Rect rct;
- ControlHandle scrollCtl;
- static Handle scrollProc;
-
- front = ((window = (*ctl)->contrlOwner) == FrontWindow());
-
- if (!scrollProc) {
- SetRect(&rct, 0, 0, 16, 100);
- scrollCtl = NewControl(window, &rct, nil, false, 0, 0, 0, scrollBarProc, 0);
- if (scrollCtl) {
- scrollProc = (*scrollCtl)->contrlDefProc;
- DisposeControl(scrollCtl);
- }
- }
-
- if ((*ctl)->contrlDefProc == scrollProc) {
- if (front) Draw1Control(ctl);
- else {
- if ((*ctl)->contrlVis) {
- GetPort(&oldPort);
- SetPort(window);
- rct = (*ctl)->contrlRect;
- FrameRect(&rct);
- InsetRect(&rct, 1, 1);
- EraseRect(&rct);
- SetPort(oldPort);
- }
- }
- }
- else if (!scrollBarsOnly) Draw1Control(ctl);
- }
-
-
-
-